--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_houjuu_nue = General:new(extension, "hy_houjuu_nue", "chi_k", 4, 4, General.Female)

    local puzzle_shape = fk.CreateSkill {
        name = "puzzle_shape",
    }
    puzzle_shape:addEffect(fk.GameStart, {
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(puzzle_shape.name) and table.any(player:getCardIds("h"), function(id)
                return not HY.IsCardPublicized(Fk:getCardById(id))
            end)
        end,
        on_cost = function(self, event, target, player, data)
            local room = player.room
            local cards = room:askToCards(player, {
                min_num = 1,
                max_num = #player:getCardIds("h"),
                skill_name = puzzle_shape.name,
                prompt = "puzzle_shape_prompt",
                pattern = ".|.|.|.|.|.|^(" .. table.concat(table.filter(player:getCardIds("h"), function(id)
                    return HY.IsCardPublicized(Fk:getCardById(id))
                end), ",") .. ")"
            })
            if type(cards) == "number" then
                cards = { cards }
            end
            if #cards > 0 then
                event:setCostData(self, cards)
                return true
            end
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            HY.SetCardPublicize(room, event:getCostData(self))
        end
    })
    puzzle_shape:addEffect(fk.EventPhaseStart, {
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(puzzle_shape.name) and table.any(player:getCardIds("h"), function(id)
                return not HY.IsCardPublicized(Fk:getCardById(id)) and target == player and player.phase == Player.Play
            end)
        end,
        on_cost = function(self, event, target, player, data)
            local room = player.room
            local cards = room:askToCards(player, {
                min_num = 1,
                max_num = #player:getCardIds("h"),
                skill_name = puzzle_shape.name,
                prompt = "puzzle_shape_prompt",
                pattern = ".|.|.|.|.|.|^(" .. table.concat(table.filter(player:getCardIds("h"), function(id)
                    return HY.IsCardPublicized(Fk:getCardById(id))
                end), ",") .. ")"
            })
            if type(cards) == "number" then
                cards = { cards }
            end
            if #cards > 0 then
                event:setCostData(self, cards)
                return true
            end
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            HY.SetCardPublicize(room, event:getCostData(self))
        end
    })
    puzzle_shape:addEffect(fk.AfterCardsMove, {
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(puzzle_shape.name) and table.any(data, function(move)
                return move.from == player and table.any(move.moveInfo, function(info)
                    return info.is_publicized and (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip)
                end)
            end) and table.any(player.room:getOtherPlayers(player), function(t)
                return table.any(t:getCardIds("h"), function(id)
                    return not HY.IsCardPublicized(Fk:getCardById(id))
                end)
            end)
        end,
        on_cost = function(self, event, target, player, data)
            local room = player.room
            local targets = table.filter(room:getOtherPlayers(player), function(t)
                return table.any(t:getCardIds("h"), function(id)
                    return not HY.IsCardPublicized(Fk:getCardById(id))
                end)
            end)
            local skillTarget = room:askToChoosePlayers(player, {
                targets = targets,
                min_num = 1,
                max_num = 1,
                skill_name = puzzle_shape.name,
                prompt = "puzzle_shape_prompt_other"
            })
            if #skillTarget == 1 then
                event:setCostData(self, skillTarget[1])
                return true
            end
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local skillTarget = event:getCostData(self)
            local visible = {}
            for _, id in ipairs(skillTarget:getCardIds("h")) do
                if not player:cardVisible(id) then
                    visible[tostring(id)] = false
                end
            end
            if next(visible) == nil then visible = nil end
            local cards = room:askToPoxi(player, {
                poxi_type = "puzzle_shape_select",
                data = { { Fk:translate("hand_card"), skillTarget:getCardIds("h") } },
                extra_data = {
                    visible_data = visible,
                    target = skillTarget.id
                },
                cancelable = false,
            })
            HY.SetCardPublicize(room, cards)
            if table.every(skillTarget:getCardIds("h"), function(id)
                    return HY.IsCardPublicized(Fk:getCardById(id))
                end) then
                room:drawCards(player, 1, puzzle_shape.name)
            end
        end
    })
    Fk:addPoxiMethod {
        name = "puzzle_shape_select",
        card_filter = function(to_select, selected, data)
            if HY.IsCardPublicized(Fk:getCardById(to_select)) then
                return false
            end
            return #selected < 1
        end,
        feasible = function(selected, data)
            return #selected == 1
        end,
        prompt = function(data, extra_data)
            return "puzzle_shape_prompt_publicize::" .. extra_data.target
        end,
        default_choice = function(data)
            local cardIds = {}
            for _, d in ipairs(data) do
                table.insertTable(cardIds, d[2])
            end
            return table.random(cardIds, 1)
        end,
        post_select = function(selected, data)
            return selected
        end,
    }

    local confuse_feeling = fk.CreateSkill {
        name = "confuse_feeling",
    }
    confuse_feeling:addEffect("viewas", {
        mute_card = false,
        pattern = ".",
        card_filter = function(self, player, to_select, selected, selected_targets)
            if table.contains(player:getTableMark("confuse_feeling-turn"), Fk:getCardById(to_select).type) then
                return false
            end
            if Fk:getCardById(to_select).type == Card.TypeEquip then
                return false
            end
            if not HY.IsCardPublicized(Fk:getCardById(to_select)) then
                return false
            end
            return #selected < 1
        end,
        interaction = function(self, player)
            local results = {}
            if not table.contains(player:getTableMark("confuse_feeling-turn"), Card.TypeBasic) then
                for _, name in ipairs(Fk:getAllCardNames("b")) do
                    local card = Fk:cloneCard(name)
                    if Fk.currentResponsePattern == nil and player:canUse(card) then
                        table.insertIfNeed(results, name)
                    elseif Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card) then
                        table.insertIfNeed(results, name)
                    end
                end
            end
            if not table.contains(player:getTableMark("confuse_feeling-turn"), Card.TypeTrick) then
                for _, name in ipairs(Fk:getAllCardNames("t")) do
                    local card = Fk:cloneCard(name)
                    if Fk.currentResponsePattern == nil and player:canUse(card) then
                        table.insertIfNeed(results, name)
                    elseif Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card) then
                        table.insertIfNeed(results, name)
                    end
                end
            end
            if #results == 0 then
                return
            end
            return UI.ComboBox { choices = results }
        end,
        prompt = function(self, player, selected_cards, selected)
            return "confuse_feeling_prompt"
        end,
        view_as = function(self, player, cards)
            if #cards ~= 1 or not self.interaction.data then return end
            local card = Fk:cloneCard(self.interaction.data)
            if card.type ~= Fk:getCardById(cards[1]).type then
                return
            end
            card:addSubcards(cards)
            return card
        end,
        before_use = function(self, player, use)
            local marks = player:getTableMark("confuse_feeling-turn")
            table.insertIfNeed(marks, use.card.type)
            player.room:setPlayerMark(player, "confuse_feeling-turn", marks)
        end,
        enabled_at_play = function(self, player)
            return table.any(player:getCardIds("h"), function(id)
                local card = Fk:getCardById(id)
                return HY.IsCardPublicized(card) and card.type ~= Card.TypeEquip and not table.contains(player:getTableMark("confuse_feeling-turn"), card.type)
            end)
        end,
        enabled_at_response = function(self, player, response)
            if response then
                return false
            end
            return table.any(player:getCardIds("h"), function(id)
                local card = Fk:getCardById(id)
                local names = card.type == Card.TypeBasic and Fk:getAllCardNames("b") or Fk:getAllCardNames("t")
                return HY.IsCardPublicized(card) and card.type ~= Card.TypeEquip and not table.contains(player:getTableMark("confuse_feeling-turn"), card.type) and Fk.currentResponsePattern and
                    table.any(names, function(name)
                        return Fk.currentResponsePattern:match(name)
                    end)
            end)
        end,
        enabled_at_nullification = function(self, player, data)
            return table.any(player:getCardIds("h"), function(id)
                local card = Fk:getCardById(id)
                local names = card.type == Card.TypeBasic and Fk:getAllCardNames("b") or Fk:getAllCardNames("t")
                return HY.IsCardPublicized(card) and card.type ~= Card.TypeEquip and not table.contains(player:getTableMark("confuse_feeling-turn"), card.type) and Fk.currentResponsePattern and
                    table.any(names, function(name)
                        return Fk.currentResponsePattern:match(name)
                    end)
            end)
        end,
    })

    extension:loadSkillSkels { puzzle_shape, confuse_feeling }
    hy_houjuu_nue:addSkills { "puzzle_shape", "confuse_feeling" }

    Fk:loadTranslationTable {
        ["hy_houjuu_nue"] = "封兽鵺",
        ["#hy_houjuu_nue"] = "奇美拉",
        ["illustrator:hy_houjuu_nue"] = "渡コキュー",
        ["designer:hy_houjuu_nue"] = "黑曜人形",
        ["cv:hy_houjuu_nue"] = "",

        ["puzzle_shape"] = "惑形",
        [":puzzle_shape"] = "游戏开始时或出牌阶段开始时，你可以<a href = 'hy_card_publicize'>明置</a>任意张手牌。在你失去<a href = 'hy_card_publicize'>明置</a>的牌后，你可以<a href = 'hy_card_publicize'>明置</a>一名其他角色一张手牌，若其因此<a href = 'hy_card_publicize'>明置</a>了全部手牌，你摸一张牌。",
        ["puzzle_shape_prompt"] = "惑形：你可以明置任意张手牌",
        ["puzzle_shape_prompt_other"] = "惑形：你可以明置一名角色一张手牌",
        ["puzzle_shape_prompt_publicize"] = "惑形：明置%dest一张手牌",
        ["puzzle_shape_select"] = "惑形",

        ["confuse_feeling"] = "淆知",
        [":confuse_feeling"] = "每回合每类型限一次，你可以将一张<a href = 'hy_card_publicize'>明置</a>的基本牌/锦囊牌当作任意基本牌/普通锦囊牌使用。",
        ["confuse_feeling_prompt"] = "淆知：你可以将一张明置的基本牌/锦囊牌当作任意基本牌/普通锦囊牌使用",
    }
end
